package tiled.core;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Properties;

public class Tile
{
    private Image internalImage, scaledImage;
    private int id = -1;
    protected int tileImageId = -1;
    private int groundHeight;
    private int tileOrientation;
    private double myZoom = 1.0;
    private Properties properties;
    private TileSet tileset;

    public Tile()
    {
        properties = new Properties();
    }

    public Tile(TileSet set)
    {
        this();
        setTileSet(set);
    }

    public Tile(Tile t)
    {
        properties = (Properties)t.properties.clone();
        tileImageId = t.tileImageId;
        tileset = t.tileset;
        if (tileset != null)
        {
            scaledImage = getImage().getScaledInstance(
                    -1, -1, Image.SCALE_DEFAULT);
        }
    }

    public void setId(int i)
    {
        if (i >= 0)
        {
            id = i;
        }
    }

    public void setImage(Image i)
    {
        if (tileset != null)
        {
            tileset.overlayImage(tileImageId, i);
        }
        else
        {
            internalImage = i;
        }
    }

    public void setImage(int id)
    {
        tileImageId = id;
    }

    public void setImageOrientation(int orientation)
    {
        thisOrientation = orientation;
    }

    public void setTileSet(TileSet set)
    {
        if (tileset != null && tileset != set)
        {
            setImage(set.addImage(getImage());
        }
        else
        {
            if (internalImage != null)
            {
                setImage(set.addImage(internalImage));
                internalImage = null;
            }
        }
        tileset = set;
    }

    public void setProperties(Properties p)
    {
        properties = p;
    }

    public Properties getProperties()
    {
        return properties;
    }

    public int getId()
    {
        return id;
    }

    public int getGid()
    {
        if (tileset != null)
        {
            return id + tileset.getFirstGid();
        }
        return id;
    }

    public TileSet getTileSet()
    {
        return tileset;
    }

    public void drawRaw(Graphics g, int x, int y, double zoom)
    {
        Image img = getScaledImage(zoom);
        if (img != null)
        {
            g.drawImage(img, x, y - img.getHeight(null), null);
        }
        else
        {
        }
    }

    public void draw(Graphics g, int x, int y, double zoom)
    {
        int gnd_h = (int)(groundHeight * zoom);
        drawRaw(g, x, y - gnd_h, zoom);
    }

    public int getWidth()
    {
        if (tileset != null)
        {
            Dimension d = tileset.getImageDimensions(tileImageId);
            return d.width;
        }
        else if (internalImage != null)
        {
            return internalImage.getWidth(null);
        }
        return 0;
    }

    public int getHeight()
    {
        if (tileset != null)
        {
            Dimension d = tileset.getImageDimensions(tileImageId);
            return d.height;
        }
        else if (internalImage != null)
        {
            return internalImage.getHeight(null);
        }
        return 0;
    }

    public int getImageId()
    {
        return tileImageId;
    }

    public int getImageOrientation()
    {
        return tileOrientation;
    }

    public Image getImage()
    {
        if (tileset != null)
        {
            return tileset.getImageById(tileImageId);
        }
        else
        {
            return internalImage;
        }
    }

    public Image getScaledImage(double zoom)
    {
        if (zoom == 1.0)
        {
            return getImage();
        }
        else if (zoom == myZoom && scaledImage != null)
        {
            return scaledImage;
        }
        else
        {
            Image img = getImage();
            if (img != null)
            {
                scaledImage = img.getScaledInstance(
                        (int)(getWidth() * zoom), (int)(getHeight() * zoom),
                        BufferedImage.SCALE_SMOOTH);

                MediaTracker mediaTracker = new MediaTracker(new Canvas());
                mediaTracker.addImage(scaledImage, 0);
                try
                {
                    mediaTracker.waitForID(0);
                }
                catch(InterruptedException ie)
                {
                    System.err.println(ie);
                }
                mediaTracker.removeImage(scaledImage);
                myZoom = zoom;
                return scaledImage;
            }
        }

        return null;
    }

    public String toString()
    {
        return "Tile " + id + " (" + getWidth() + "x" + getHeight() + ")";
    }
}
